package cn.swust.designpatternlearningplatform.controller;

import cn.swust.designpatternlearningplatform.common.AnnotationUtils.Authentication;
import cn.swust.designpatternlearningplatform.common.Result.PageInfo;
import cn.swust.designpatternlearningplatform.common.Result.R;
import cn.swust.designpatternlearningplatform.common.utils.AuthUserContext;
import cn.swust.designpatternlearningplatform.common.utils.JwtUtils;
import cn.swust.designpatternlearningplatform.domain.bo.*;
import cn.swust.designpatternlearningplatform.domain.dto.*;
import cn.swust.designpatternlearningplatform.domain.entity.DailyExercise;
import cn.swust.designpatternlearningplatform.domain.entity.KnowledgePoint;
import cn.swust.designpatternlearningplatform.domain.entity.Topic;
import cn.swust.designpatternlearningplatform.domain.entity.TopicOption;
import cn.swust.designpatternlearningplatform.domain.enums.RoleEnum;
import cn.swust.designpatternlearningplatform.domain.enums.TopicDiffEnum;
import cn.swust.designpatternlearningplatform.domain.enums.TopicTypeEnum;
import cn.swust.designpatternlearningplatform.domain.enums.TopicUpdateTypeEnum;
import cn.swust.designpatternlearningplatform.domain.vo.TopicCollectVo;
import cn.swust.designpatternlearningplatform.domain.vo.TopicShieldVo;
import cn.swust.designpatternlearningplatform.domain.vo.TopicVo;
import cn.swust.designpatternlearningplatform.service.*;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.websocket.server.PathParam;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/topic")
public class TopicController {
    /**
     * 题目
     *
     * @author Tang
     * @date 2023/5/2 22:05
     **/
    @Resource
    private TopicService topicService;

    /**
     * 题目知识点
     *
     * @author Tang
     * @date 2023/5/2 22:06
     **/
    @Resource
    private TopicKnowledgePointService topicKnowledgePointService;

    /**
     * 做题记录
     *
     * @author Tang
     * @date 2023/5/2 22:06
     **/
    @Resource
    private DailyExerciseService dailyExerciseService;

    /**
     * 题目更新操作
     */
    @Resource
    private TopicUpdateService topicUpdateService;

    /**
     * 获取知识点
     *
     * @param knowledgePointId
     * @return cn.swust.designpatternlearningplatform.common.Result.R<java.util.List < cn.swust.designpatternlearningplatform.domain.dto.KnowledgePointDto>>
     * @author Tang
     * @date 2023/4/16 2:37
     **/
    @Authentication
    @GetMapping("/point/getKnowledgePoint")
    public R<List<KnowledgePointDto>> getKnowledgePoint(@PathParam("knowledgePointId") Integer knowledgePointId) {
        List<KnowledgePointDto> knowledgePointDtoList = topicKnowledgePointService.getKnowledgePointSonId(knowledgePointId).stream().map(i -> {
            Integer pointId = i.getPointId();
            KnowledgePoint knowledgePointById = topicKnowledgePointService.getKnowledgePointById(pointId);
            KnowledgePointDto knowledgePointDto = new KnowledgePointDto();
            BeanUtils.copyProperties(knowledgePointById, knowledgePointDto);
            return knowledgePointDto;
        }).collect(Collectors.toList());
        return R.success(knowledgePointDtoList);
    }

    /**
     * 添加题目
     *
     * @param topicVo
     * @return cn.swust.designpatternlearningplatform.common.Result.R<java.lang.String>
     * @author Tang
     * @date 2023/5/24 13:02
     **/
    @Authentication(RoleEnum.TEACHER)
    @PostMapping({"/add"})
    public R<String> addTopicPlaintext(@RequestBody TopicVo topicVo) {
        TopicBo topicBo = topicVo2TopicBo(topicVo);
        TopicKpointBo topicKpointBo = topicVo2TopicKpointBo(topicVo);
        TopicOptionsBo topicOptionsBo = topicVo2TopicOptionsBo(topicVo);
        topicService.addTopic(topicBo, topicKpointBo, topicOptionsBo);
        return R.success("录入成功");
    }

    /**
     * 批量导入题目
     *
     * @param file
     * @return cn.swust.designpatternlearningplatform.common.Result.R<java.lang.String>
     * @author Tang
     * @date 2023/7/8 13:24
     **/
    @Authentication
    @PostMapping("/addByExcel")
    public R<String> addTopicByExcel(@RequestPart("excel") MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || !originalFilename.endsWith(".xlsx")) {
            return R.success("文件格式错误");
        }
        topicService.addTopicByExcel(file);
        return R.success("完全上传成功");
    }

    /**
     * 查询题目（老师和学生查询的信息不同）
     *
     * @param currentPage
     * @param pageSize
     * @return cn.swust.designpatternlearningplatform.common.Result.R<cn.swust.designpatternlearningplatform.common.Result.PageInfo < cn.swust.designpatternlearningplatform.domain.dto.TopicDto>>
     * @author Tang
     * @date 2023/5/24 13:02
     **/
    @Authentication(RoleEnum.TEACHER)
    @GetMapping("/getTopic")
    public R<PageInfo<TopicDto>> getTopic(@RequestParam("current") Integer currentPage,
                                          @RequestParam("pageSize") Integer pageSize,
                                          @RequestParam(value = "pointId", required = false) Integer pointId) {
        //如果是学生查询，则不返回答案，解析，解析图片路径，难度
        String role = AuthUserContext.get().getRole();

        String[] ignore = {""};
        if (role.equals(RoleEnum.STUDENT.getRoleName())) {
            ignore = new String[]{"topicAnswer", "topicAnalyse", "topicAnalysePath", "topicDifficulty"};
        }
        PageInfo<TopicDto> pageInfo = new PageInfo<>();
        pageInfo.setCurrentPage(currentPage);
        pageInfo.setPageSize(pageSize);
        pageInfo = topicService.selectByPage(pageInfo, pointId, ignore);
        return R.success(pageInfo);
    }

    @Authentication(RoleEnum.STUDENT)
    @GetMapping("/getTopicRecord")
    public R<PageInfo<TopicDto>> getTopicRecord(@RequestParam("current") Integer currentPage,
                                                @RequestParam("pageSize") Integer pageSize,
                                                @RequestParam(value = "pointId", required = false) Integer pointId) {
        String number = AuthUserContext.get().getNumber();
        PageInfo<TopicDto> dtoPageInfo = topicService.getTopicByStudentNumber(number, pointId, currentPage, pageSize);
        return R.success(dtoPageInfo);
    }


    /**
     * 获取知识点分布
     *
     * @param
     * @return cn.swust.designpatternlearningplatform.common.Result.R<java.util.List < cn.swust.designpatternlearningplatform.domain.dto.KnowledgePointDto>>
     * @author Tang
     * @date 2023/7/18 14:15
     **/
    @Authentication
    @GetMapping("/getKnowPoints")
    public R<List<KnowledgePointDto>> getKnowPointsInTopicUpdate(@RequestParam("updateType") Integer updateType,
                                                                 @RequestParam(value = "topicType", required = false) Integer topicType) {
        String number = AuthUserContext.get().getNumber();
        List<KnowledgePointDto> knowledgePointInTopicType = topicUpdateService.getKnowledgePointInTopicType(number,
                TopicUpdateTypeEnum.topicUpdateType(updateType),
                TopicTypeEnum.topicType(topicType));
        return R.success(knowledgePointInTopicType);
    }

    /**
     * 获取难度分布
     *
     * @param updateType
     * @param topicType
     * @return cn.swust.designpatternlearningplatform.common.Result.R<java.util.List < cn.swust.designpatternlearningplatform.domain.dto.KnowledgePointDto>>
     * @author Tang
     * @date 2023/7/18 14:59
     **/
    @Authentication
    @GetMapping("/getDifficulty")
    public R<DifficultyDto> getDifficultyInTopicUpdate(@RequestParam("updateType") Integer updateType,
                                                       @RequestParam(value = "topicType", required = false) Integer topicType) {
        String number = AuthUserContext.get().getNumber();
        DifficultyDto difficultyDistribution = topicUpdateService.getDifficultyDistribution(number,
                TopicUpdateTypeEnum.topicUpdateType(updateType),
                TopicTypeEnum.topicType(topicType));
        return R.success(difficultyDistribution);
    }

    /**
     * 修改题目
     *
     * @param topicVo
     * @return cn.swust.designpatternlearningplatform.common.Result.R<java.lang.String>
     * @author Tang
     * @date 2023/7/22 11:29
     **/
    @Authentication(RoleEnum.TEACHER)
    @PutMapping({"/editTopic"})
    public R<String> editTopic(@RequestBody TopicVo topicVo) {
        TopicBo topicBo = topicVo2TopicBo(topicVo);
        TopicKpointBo topicKpointBo = topicVo2TopicKpointBo(topicVo);
        TopicOptionsBo topicOptionsBo = topicVo2TopicOptionsBo(topicVo);
        topicService.updateTopic(topicBo, topicKpointBo, topicOptionsBo);
        return R.success("修改成功");
    }

    /**
     * 批量删除题目
     *
     * @param data
     * @return cn.swust.designpatternlearningplatform.common.Result.R<java.lang.String>
     * @author Tang
     * @date 2023/7/22 11:41
     **/
    @Authentication(RoleEnum.TEACHER)
    @DeleteMapping({"/batchDeleteTopic"})
    public R<String> batchDeleteTopic(@RequestBody List<Integer> data) {
        topicService.batchDelete(data);
        return R.success("删除成功");
    }


    private TopicBo topicVo2TopicBo(TopicVo topicVo) {
        TopicBo topicBo = new TopicBo();
        BeanUtils.copyProperties(topicVo, topicBo);
        topicBo.setTopicType(TopicTypeEnum.topicType(topicVo.getTopicType()));
        topicBo.setTopicDifficulty(TopicDiffEnum.topicDiff(topicVo.getTopicDifficulty()));
        return topicBo;
    }

    private TopicKpointBo topicVo2TopicKpointBo(TopicVo topicVo) {
        TopicKpointBo topicKpointBo = new TopicKpointBo();
        topicKpointBo.setPointIds(topicVo.getPointId());
        return topicKpointBo;
    }

    private TopicOptionsBo topicVo2TopicOptionsBo(TopicVo topicVo) {
        TopicOptionsBo topicOptionsBo = new TopicOptionsBo();
        topicOptionsBo.setTopicOptions(topicVo.getTopicOptionVos());
        return topicOptionsBo;
    }
}
